/**
 * Copyright (c) 2015-2017, Henry Yang 杨勇 (gismail@foxmail.com).
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lambkit.plugin.activerecord.dialect;

import com.jfinal.plugin.activerecord.IRow;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.SqlPara;
import com.lambkit.db.IRowData;
import com.lambkit.db.Sql;
import com.lambkit.db.dialect.IDialect;
import com.lambkit.db.sql.Columns;
import com.lambkit.db.sql.Example;

import java.util.List;

public interface LambkitDialect extends IDialect {

	public String forFindSql(String sql, String orderBy, Object limit);
    public String forFindByColumns(String table, String loadColumns, Columns columns, String orderBy, Object limit);
    public String forPaginateSelect(String loadColumns);
    public String forPaginateByColumns(String table, Columns columns, String orderBy);
    
    public SqlPara forFindBySqlPara(SqlPara sqlPara, String orderBy, Object limit);
    public SqlPara forFindByExample(Example example, Object limit);
    public SqlPara forPaginateByExample(Example example);
    public SqlPara forPaginateFormByExample(Example example);
    
    public SqlPara forDeleteByExample(Example example);
    
//    public SqlPara forUpdate(Record record, String tableName, QueryParas queryParas);
    public SqlPara forUpdateByExample(IRow record, Example example);

    default String selectSql(String sql, String orderBy, Object limit) {
        return forFindSql(sql, orderBy, limit);
    }
    default String selectSqlByColumns(String table, String loadColumns, Columns columns, String orderBy, Object limit) {
        return forFindByColumns(table, loadColumns, columns, orderBy, limit);
    }
    default String paginateSelect(String loadColumns) {
        return forPaginateSelect(loadColumns);
    }
    default String paginateByColumns(String table, Columns columns, String orderBy) {
        return forPaginateByColumns(table, columns, orderBy);
    }

    default Sql findBySql(Sql sql, String orderBy, Object limit) {
        SqlPara sqlPara1 = toSqlPara(sql);;
        SqlPara sqlPara2 = forFindBySqlPara(sqlPara1, orderBy, limit);
        return toSql(sqlPara2);
    }
    default Sql findByExample(Example example, Object limit) {
        return toSql(forFindByExample(example, limit));
    }
    default Sql paginateByExample(Example example) {
        return toSql(forPaginateByExample(example));
    }
    default Sql paginateFormByExample(Example example) {
        return toSql(forPaginateFormByExample(example));
    }
    default Sql deleteByExample(Example example) {
        return toSql(forDeleteByExample(example));
    }
    default Sql updateByExample(IRowData rowData, Example example) {
        Record record = new Record();
        record.put(rowData.toMap());
        return toSql(forUpdateByExample(record, example));
    }

    default SqlPara toSqlPara(Sql sql) {
        SqlPara sqlPara = new SqlPara();
        sqlPara.setSql(sql.getSql());
        List<Object> paras = sql.getParaList();
        for(int i=0; i<paras.size(); i++) {
            sqlPara.addPara(paras.get(i));
        }
        return sqlPara;
    }

    default Sql toSql(SqlPara sqlPara2) {
        Sql sql = new Sql();
        sql.setSql(sqlPara2.getSql());
        sql.setPara(sqlPara2.getPara());
        return sql;
    }

    //public String buildSQL(String queryType, String fieldName, Object fieldValue, String alias, List<Object> params);
    
    /**
	 * 用于获取 Db.save(tableName, record) 以后自动生成的主键值，可通过覆盖此方法实现更精细的控制
	 * 目前只有 PostgreSqlDialect，覆盖过此方法
	 */
	//public void getRecordGeneratedKey(PreparedStatement pst, IRow record, String[] pKeys) throws SQLException;
}
